package org.fuxia.im.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;

import org.fuxia.im.common.AquaBarTabbedPaneUI;
import org.fuxia.im.common.ClientConst;
import org.fuxia.im.common.ClientContext;
import org.fuxia.im.common.CommonDialog;
import org.fuxia.im.common.CommonListCellData;
import org.fuxia.im.common.CommonListCellModel;
import org.fuxia.im.common.CommonListCellRender;
import org.fuxia.im.common.IconManager;
import org.fuxia.im.core.ECMessageType;
import org.fuxia.im.core.entries.ECPacket;
import org.fuxia.im.entities.User;
import org.fuxia.im.gui.util.FileUtil;
import org.tony.common.ui.CommonFrame;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

@SuppressWarnings({"serial","rawtypes","unchecked"})
public class GroupChat extends CommonFrame {

	private DateFormat sdf ;
	private JPanel contentPane;
	private JPanel groupInfoPanel;
	private JLabel groupImageLabel;
	private JSplitPane hSplitPane;
	private JSplitPane vSplitPane;
	private JPanel panel;
	private JPanel toolPanel;
	private JButton chatRecord;
	private JScrollPane sendScroll;
	private JPanel sendToolPanel;
	private JButton sendMessage;
	private JButton closeWindow;
	private JScrollPane recvMessageScroll;
	private JTextPane recvMessage;
	private JTextPane sendMessagePane;
	private JScrollPane memberScroll;
	private JList membersList;
	private JLabel groupInfoLabel;
	private ImageIcon icon ;
	private Font font ;
	private String groupChatId ;
	private String[] users ;
	private Map<String,String> userNickName ;
	private String owner ;
	private boolean recordOpened; 
	private JTabbedPane tbapane ;
	private JPanel record ;
	private JScrollPane jsScroll ;
	private JEditorPane recordPanel ;
	private boolean hasAddRecordScrollIntoRcPane;
	private TitledBorder titleBorder ;
	private LineBorder lineBorder ;

	public GroupChat() {
		super() ;
		initialize();
		setContent(contentPane);
	}
	private void initialize() {
		userNickName = new HashMap<String, String>();
		sdf = new SimpleDateFormat("HH:mm:ss") ;
		font = new Font("微软雅黑",Font.PLAIN,12);
		icon = new ImageIcon(Thread.currentThread().getContextClassLoader().getResource("images\\group.jpg"));
		setTitle("多人聊天");
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		setBounds(100, 100, 752, 539);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		GridBagLayout contentPanelGbl = new GridBagLayout();
		contentPanelGbl.columnWidths = new int[]{422, 0};
		contentPanelGbl.rowHeights = new int[]{43, 195, 0};
		contentPanelGbl.columnWeights = new double[]{0.0, Double.MIN_VALUE};
		contentPanelGbl.rowWeights = new double[]{0.0, 0.0, Double.MIN_VALUE};
		contentPane.setLayout(contentPanelGbl);
		
		groupInfoPanel = new JPanel();
		groupInfoPanel.setOpaque(false);
		GridBagConstraints gbc_groupInfoPanel = new GridBagConstraints();
		gbc_groupInfoPanel.weighty = 0.04;
		gbc_groupInfoPanel.gridwidth = 2;
		gbc_groupInfoPanel.fill = GridBagConstraints.BOTH;
		gbc_groupInfoPanel.gridx = 0;
		gbc_groupInfoPanel.gridy = 0;
		contentPane.add(groupInfoPanel, gbc_groupInfoPanel);
		groupInfoPanel.setLayout(null);
		
		groupImageLabel = new JLabel("");
		groupImageLabel.setIcon(icon);
		groupImageLabel.setBounds(6, 6, 42, 42);
		groupInfoPanel.add(groupImageLabel);
		
		groupInfoLabel = new JLabel("\u8FD9\u91CC\u663E\u793A\u7FA4\u7684\u540D\u79F0(123456789)");
		groupInfoLabel.setFont(font);
		groupInfoLabel.setBounds(60, 15, 217, 18);
		groupInfoPanel.add(groupInfoLabel);
		
		hSplitPane = new JSplitPane();
		hSplitPane.setOpaque(false);
		commonSplitPaneSetUp(hSplitPane) ;
		hSplitPane.setResizeWeight(0.8);
		GridBagConstraints gbc_hSplitPane = new GridBagConstraints();
		gbc_hSplitPane.insets = new Insets(0, 0, 10, 0);
		gbc_hSplitPane.weighty = 0.94;
		gbc_hSplitPane.gridwidth = 2;
		gbc_hSplitPane.gridheight = 6;
		gbc_hSplitPane.fill = GridBagConstraints.BOTH;
		gbc_hSplitPane.gridx = 0;
		gbc_hSplitPane.gridy = 1;
		contentPane.add(hSplitPane, gbc_hSplitPane);
		
		vSplitPane = new JSplitPane();
		vSplitPane.setOpaque(false);
		vSplitPane.setResizeWeight(0.6);
		commonSplitPaneSetUp(vSplitPane) ;
		vSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
		hSplitPane.setLeftComponent(vSplitPane);
		
		panel = new JPanel();
		panel.setOpaque(false);
		vSplitPane.setRightComponent(panel);
		panel.setLayout(new BorderLayout(0, 0));
		
		toolPanel = new JPanel();
		panel.add(toolPanel, BorderLayout.NORTH);
		toolPanel.setLayout(new BorderLayout(0, 0));
		
		chatRecord = new JButton("\u804A\u5929\u8BB0\u5F55");
		chatRecord.setIcon(IconManager.getIcon("images/aio_quickbar_register.png"));
		chatRecord.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
		
				if(!recordOpened) {
					
					if(tbapane==null) {
						tbapane = new JTabbedPane() ;
						tbapane.setUI(new AquaBarTabbedPaneUI()) ;
						record = new JPanel() ;
						record.setLayout(new BorderLayout(0,0)) ;
						tbapane.addTab("聊天记录", record);
						//
					}
					initRecord();
					if(!hasAddRecordScrollIntoRcPane){
						record.add(jsScroll,BorderLayout.CENTER);
					}
					memberScroll.setBorder(lineBorder) ;
					tbapane.insertTab("用户列表", null, memberScroll, null, 0);
					hSplitPane.setRightComponent(tbapane) ;
					recordOpened = true ;
				}else {
					recordOpened = false ;
					memberScroll.setBorder(titleBorder);
					hSplitPane.setRightComponent(memberScroll);
				}
			}
		});
		toolPanel.add(chatRecord, BorderLayout.EAST);
		
		sendScroll = new JScrollPane();
		panel.add(sendScroll, BorderLayout.CENTER);
		
		sendMessagePane = new JTextPane();
		sendScroll.setViewportView(sendMessagePane);
		sendMessagePane.addKeyListener(new KeyListener() {
			boolean hasRepainted ;
			public void keyTyped(KeyEvent e) {
				update(e);
			}
			
			public void keyReleased(KeyEvent e) {
				update(e);
			}
			
			public void keyPressed(KeyEvent e) {
				update(e);
			}
			
			public void update(KeyEvent e){
				if(!hasRepainted) {
					GroupChat.this.repaint() ;
					hasRepainted = true ;
				}
			}
		});
		
		sendToolPanel = new JPanel();
		panel.add(sendToolPanel, BorderLayout.SOUTH);
		GridBagLayout gbl_sendToolPanel = new GridBagLayout();
		gbl_sendToolPanel.columnWidths = new int[]{0,0};
		gbl_sendToolPanel.rowHeights = new int[]{30, 0};
		gbl_sendToolPanel.columnWeights = new double[]{0.0, 0.0};
		gbl_sendToolPanel.rowWeights = new double[]{0.0, Double.MIN_VALUE};
		sendToolPanel.setLayout(gbl_sendToolPanel);
		
		closeWindow = new JButton("\u5173\u95ED");
		GridBagConstraints gbc_closeWindow = new GridBagConstraints();
		gbc_closeWindow.anchor = GridBagConstraints.EAST;
		gbc_closeWindow.weightx = 0.99;
		gbc_closeWindow.gridx = 0;
		gbc_closeWindow.gridy = 0;
		sendToolPanel.add(closeWindow, gbc_closeWindow);
		closeWindow.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				dispose() ;
			}
		}) ;
		
		sendMessage = new JButton("\u53D1\u9001");
		GridBagConstraints gbc_sendMessage = new GridBagConstraints();
		gbc_sendMessage.weightx = 0.01;
		gbc_sendMessage.gridy = 0;
		sendToolPanel.add(sendMessage, gbc_sendMessage);
		sendMessage.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				SwingUtilities.invokeLater(new Runnable() {
					public void run() {
						String message = sendMessagePane.getText() ;
						if(message==""||message.length()==0) {
							JOptionPane.showMessageDialog(getThis(), "发送内容不能为空","错误",JOptionPane.ERROR_MESSAGE) ;
							return ;
						}else {
							User sendedUser = ClientContext.getLoginUser();
							insertHeader(recvMessage, sendedUser.getNickName()
									+ "   " + sdf.format(new Date()));
							insertMessage(recvMessage, message);
							try {
								ClientContext.getContext().getClient().sendGroupTextMessage(message, sendedUser.getUserCode(),getGroupChatId(), getUsers()) ;
							} catch (Exception e) {
								CommonDialog.showErrorMessageDialog(getThis(), "发送消息失败，请检查网络连接");
							}
						}
						
						sendMessagePane.setText("");
					}
				});
			}
		});
		
		recvMessageScroll = new JScrollPane();
		vSplitPane.setLeftComponent(recvMessageScroll);
		
		recvMessage = new JTextPane();
		recvMessage.setEditable(false);
		recvMessageScroll.setViewportView(recvMessage);
		
		memberScroll = new JScrollPane();
		titleBorder = new TitledBorder(null, "用户列表", TitledBorder.LEADING, TitledBorder.TOP, new Font("微软雅黑", Font.BOLD, 12), null);
		lineBorder = new LineBorder(new Color(88,183,237), 1) ;
		memberScroll.setBorder(titleBorder);
		hSplitPane.setRightComponent(memberScroll);
		
		membersList = new JList();
		//membersList.setOpaque(false);
		membersList.setCellRenderer(new CommonListCellRender()) ;
		membersList.setFont(font);
		membersList.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				final int index =membersList.getSelectedIndex() ;
				if(index != -1 && e.getButton() == MouseEvent.BUTTON3) {
					CommonListCellData ccm = (CommonListCellData)membersList.getModel().getElementAt(index);
					final Object userCode = ccm.getProperties("userCode") ;
					if(userCode!=null && !userCode.toString().equals(owner)) {
						JPopupMenu jpm = new JPopupMenu();
						JMenuItem sendMessage = new JMenuItem("发送消息");
						JMenuItem removeIt = new JMenuItem("移除此人");
						removeIt.addActionListener(new ActionListener() {
							
							public void actionPerformed(ActionEvent e) {
								int result = JOptionPane.showConfirmDialog(GroupChat.this, "确认从此群组中移除该用户？") ;
								if(result== JOptionPane.OK_OPTION) {
									ECPacket p = new ECPacket() ;
									p.setMessageType(ECMessageType.GROUP_OP.name()) ;
									p.setFrom(ClientContext.getLoginUser().getUserCode()) ;
									p.addParam("groupId", getGroupChatId()) ;
									p.addParam("userCode", userCode.toString());
									p.addParam("option", "removeUser");
									try {
										ClientContext.putValue(ClientConst.CURRENT_REQUESTOR, GroupChat.this);
										ClientContext.getContext().getClient().sendMessage(p);
										((DefaultListModel)membersList.getModel()).remove(index);
										membersList.revalidate();
										ClientContext.removeUserInGroup(userCode.toString(), getGroupChatId());
										reGenUsers();
									} catch (Exception e1) {
									}
								}
								
							}
						});
						jpm.add(sendMessage);
						jpm.add(removeIt) ;
						jpm.show(membersList, e.getX(), e.getY()) ;
					}
				}
			}
		});
		memberScroll.setViewportView(membersList);
		
		addWindowListener(new WindowAdapter() {

			@Override
			public void windowClosed(WindowEvent e) {
				ClientContext.removeKey(getGroupChatId()) ;
			}
			
		});
	}
	
	private void commonSplitPaneSetUp(JSplitPane sp){
		sp.setBorder(null); 
		sp.setOneTouchExpandable(false);
		sp.setOpaque(false);
		sp.setResizeWeight(0.7D);
		sp.setDividerSize(1);
	}
	
	private void insert(JEditorPane editorPane, String str, AttributeSet asst) {
		int lenth = editorPane.getDocument().getLength();
		try {
			editorPane.getDocument().insertString(lenth, str + "\n", asst);
			editorPane.setCaretPosition(editorPane.getDocument().getLength());
			editorPane.repaint() ;
		} catch (BadLocationException e) {
			//no ops
		} catch (Exception e) {
			// no ops
		}
	}

	private void insertHeader(JEditorPane editorPane, String str) {
		SimpleAttributeSet attrSet = new SimpleAttributeSet();
		StyleConstants.setFontFamily(attrSet, "微软雅黑");
		StyleConstants.setForeground(attrSet, Color.BLUE);
		insert(editorPane, str, attrSet);
	}

	public void insertOtherUserHeader(String userCode) {
		String nickName = userNickName.get(userCode) ;
		nickName = nickName == null?userCode:nickName;
		SimpleAttributeSet attrSet = new SimpleAttributeSet();
		StyleConstants.setFontFamily(attrSet, "微软雅黑");
		StyleConstants.setForeground(attrSet, Color.GREEN);
		insert(this.recvMessage, nickName + "   " + sdf.format(new Date()),
				attrSet);
	}
	
	public void insertRecvMessae(String message) {
		insertMessage(this.recvMessage, message);
	}
	
	private void insertMessage(JEditorPane editorPane, String str) {
		SimpleAttributeSet attrSet = new SimpleAttributeSet();
		StyleConstants.setFontFamily(attrSet, "微软雅黑");
		StyleConstants.setForeground(attrSet, Color.BLACK);
		insert(editorPane, str, attrSet);
	}
	
	/**
	 * 重新生成用户成员
	 */
	protected void reGenUsers(){
		JSONObject obj = ClientContext.findChatGroupById(groupChatId);
		if(obj !=null) {
			JSONArray js = ((JSONArray)obj.get("users")) ;
			if(js.size()>1) {
				String[] users = new String[js.size()-1 ] ;
				int j = 0 ;
				for(int i=0;i<js.size();i++) {
					JSONArray data = js.getJSONArray(i);
					if(!data.getString(0).equals(owner)) {
						users[j++] = data.getString(0) ;
					}
				}
				setUsers(users);
			}
		}
	}
	
	@Override
	public void dispose() {
		super.dispose();
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				String recordFilePath = ClientContext.getValue("group-record-save-path", String.class) ;
				if(recordFilePath != null) {
					FileUtil.writeMessage(MessageFormat.format(recordFilePath, getGroupChatId()), getMessageRecord());
				}
			}
		});
	}
	
	protected String getMessageRecord(){
		int len = recvMessage.getDocument().getLength();
		try {
			return recvMessage.getDocument().getText(0, len) ;
		} catch (BadLocationException e) {
		}
		return "" ;
	}
	
	private void initRecord() {
		if(jsScroll == null) {
			jsScroll = new JScrollPane() ;
			jsScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER) ;
			recordPanel = new JEditorPane() ;
			recordPanel.setEditable(false);
			recordPanel.setContentType("text/html");
			jsScroll.setViewportView(recordPanel);
		}
		String recordFilePath = ClientContext.getValue("group-record-save-path", String.class) ;
		Map<String,String> record = FileUtil.readRecord(MessageFormat.format(recordFilePath, getGroupChatId())) ;
		if(record!=null) {
			recordPanel.setText("");
			SimpleAttributeSet attrSet = new SimpleAttributeSet();
			StyleConstants.setFontFamily(attrSet, "微软雅黑");
			StyleConstants.setForeground(attrSet, Color.RED);
			StyleConstants.setFontSize(attrSet, 14);
			for(Iterator<String> keyIter = record.keySet().iterator();keyIter.hasNext();) {
				String key = keyIter.next() ;
				insert(recordPanel,String.format("-----------%s------------", key),attrSet);
				insertMessage(recordPanel, record.get(key)) ;
			}
		}
	}
	
	public void showGroupChatWindow(String groupChatId){
		setGroupChatId(groupChatId);
		List<JSONObject> chatGroups = ClientContext.getValue(ClientConst.GROUPS,List.class) ;
		
		if(chatGroups!=null) {
			CommonListCellModel ccm = new CommonListCellModel() ;	
			ccm.setDisplayField("nickName") ;
			for(JSONObject obj:chatGroups){
				if(obj.getString("id").equals(groupChatId.trim())) {
					this.groupInfoLabel.setText(String.format("%s(%s)", obj.getString("groupName"),obj.getString("id"))) ;
					List<JSONArray> jsonUsers = (List<JSONArray>) obj.get("users") ;
					if(jsonUsers!=null) {
						String[] users = new String[jsonUsers.size()-1] ;
						int i = 0 ;
						for(JSONArray user:jsonUsers) {
							String uCode = user.getString(0) ;
							String iconPath ;
							String nickName = user.getString(1);
							if(uCode.equals(obj.getString("ownerId"))) {
								iconPath = "images/owner.png" ;
								nickName+= "(群主)";
								owner = uCode ;
 							}else {
 								iconPath = "images/member.png" ;
 							}
							if(!ClientContext.getLoginUser().getUserCode().equals(uCode)) {
								users[i++] = uCode ;
							}
							userNickName.put(uCode, nickName);
							ccm.addRow(new Object[][]{
									new Object[]{"userCode",user.getString(0)},
									new Object[]{"nickName",nickName},
									new Object[]{"icon",iconPath}});
						}
						setUsers(users);
					}
				}
			}
			membersList.setModel(ccm);
		}
		setVisible(true);
	}

	public String[] getUsers() {
		return users;
	}

	public void setUsers(String[] users) {
		this.users = users;
	}

	public String getGroupChatId() {
		return groupChatId;
	}

	public void setGroupChatId(String groupChatId) {
		this.groupChatId = groupChatId;
	}
	
	
	protected JFrame getThis(){
		return this ;
	}

}
